package com.third.customer.site.support;

import com.third.customer.model.dao.UserDao;
import com.third.customer.model.data.UserType;
import com.third.customer.model.tables.User;
import com.third.customer.service.client.RedisClient;
import com.third.customer.service.data.UserLoginData;
import com.third.customer.service.exception.ThirdForbiddenException;
import com.third.customer.service.exception.ThirdNotFoundException;
import com.third.customer.site.Constants;
import com.third.customer.site.UserInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Objects;

/**
 * Created by hehuaichun on 2020/5/20.
 */
@Slf4j
public class AuthInterceptor extends HandlerInterceptorAdapter {

    private RedisClient redisClient;

    private UserDao userDao;

    public AuthInterceptor(RedisClient redisClient, UserDao userDao) {
        this.redisClient = redisClient;
        this.userDao = userDao;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (handler instanceof HandlerMethod) {
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            ThirdAuth annotation = handlerMethod.getMethodAnnotation(ThirdAuth.class);
            if (annotation != null) {
                //查询账户
                String token = request.getHeader(Constants.THIRD_TOKEN);
                UserLoginData userLoginData = redisClient.getLoginUserPair(token)
                        .orElseThrow(() -> new ThirdForbiddenException("您需要重新登录"));
                User user = userDao.getByName(userLoginData.getCompanyId(), userLoginData.getUserName())
                        .orElseThrow(() -> new ThirdNotFoundException("您需要重新登录!"));

                //将账户存到request中
                UserInfo userInfo = new UserInfo(user, token);
                request.setAttribute(Constants.ATTRIBUTE_USER, userInfo);

                //验证权限是否足够
                UserType needAuth = annotation.value();
                UserType userAuth = UserType.codeOf(user.getType());
                if (UserType.ADMIN.equals(needAuth) && !Objects.equals(userAuth, needAuth)) {
                    throw new ThirdForbiddenException("当前功能您没有权限访问!");
                }
            }
        }
        return true;
    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        if (handler instanceof HandlerMethod) {
            //访问后自动刷新登录时间
            HandlerMethod handlerMethod = (HandlerMethod) handler;
            ThirdAuth annotation = handlerMethod.getMethodAnnotation(ThirdAuth.class);
            if (annotation != null) {
                UserInfo userInfo = (UserInfo) request.getAttribute(Constants.ATTRIBUTE_USER);
                if (userInfo != null) {
                    redisClient.setLoginToken(userInfo.getCompanyId(), userInfo.getUser().getName(), userInfo.getToken(), false);
                }

            }
        }
    }
}
